package com.xinz.srmi;

import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;

import com.xinz.srmi.NativeInvokFilter.ListFilter;

/***
 * 远程调用层 RemoteInvoker<br>
 * 序列化层 Serializer <br>
 * 传输层 InvokConnector<br>
 * <p>
 * 传输层 Connector? <br>
 * 序列化层 Serializer <br>
 * 本地调用层 NativeInvoker <br>
 * 序列化层 Serializer <br>
 * 传输层  Connector?
 * </p>
 * 传输层 InvokConnector <br>
 * 序列化层 Serializer <br>
 * 远程调用层 RemoteInvoker
 * 
 * @author xingyun
 * 
 */
public class NativeInvoker {

	
	ConfigFactory foctyoy;
	
	/**
	 * 
	 * @param context
	 * @param serializer
	 */
//	public NativeInvoker(ResponseHeaderProvider headerProvider,Serializer serializer) {
//		this.headerProvider = headerProvider;
//		this.serializer = serializer;
//		implementers = new Object[context.getInterfaceSize()];
//		interfaceFilter = new InterfaceFilter(context);
//		filterList.add(interfaceFilter);
//	}
//	

	public NativeInvoker(ConfigFactory foctyoy) {
		this.foctyoy = foctyoy;
	}
//	
	public Buffer invoke(Session session,Buffer request) {
		Session.setCurrent(session);
		try{
			// 调用序列化层，把方法调用的细节序列化层字节数组
			ResponseHeaderProvider headerProvider = foctyoy.getNativeConfig().getResponseHeaderProvider();
			Serializer serializer = foctyoy.getShareConfig().getSerializer();
			ErrorHandler handler = foctyoy.getNativeConfig().getErrorHandler();
			NativeInvokFilter filter = foctyoy.getNativeConfig().getNativeInvokFilter();
			NativeMethod method = serializer.parseMethod(session, request);
			
			Object result = null;
			boolean isException = false;
			try {
				if (method == null) {
					result = handler.interfaceNotFind(method);
				}else{
					Object obj = session.findImplement(method.method);
					if (obj == null) {
						result = handler.implementerNotFind(method);
					}else{
						//最终调用本地实现
						filter.readyInvok(method);
						try{
							result = method.invok(obj);
						}catch (InvocationTargetException e) {
							throw filter.invokException(method,e);
						}
						filter.invokSuccess(method);
						session.setTag("method_mame", method.method.getName());
					}
				}
			} catch (InvocationTargetException e) {
				Throwable targetException = e.getTargetException();
				targetException.printStackTrace();
				if (targetException instanceof ServiceException) {
					result =  targetException;
				}else{
					result = new ServiceException("服务异常，请稍后再试:"+targetException);
				}
				isException = true;
			} catch (ServiceException e) {
				result = e;
				isException = true;
				e.printStackTrace();
			} catch (Exception e) {
				result = new ServiceException("系统异常，请稍后再试:"+e);
				isException = true;
				e.printStackTrace();
			}
			
	//		logTime(method.getMethod().getName()+" invokNative:");
			Object responseHeader = null;
			try{
				responseHeader = headerProvider.provideResponseHeader(session, method.method,method.requestHeader,method.args
						,isException,result);
	//			logTime(method.getMethod().getName()+" provideResponseHeader:");
			}catch (ServiceException e) {
				//抓取ServiceException  直接抛到客户端
				result = e;
				isException = true;
				e.printStackTrace();
			}catch (Exception e) {
				//其他异常则包装成ServiceException然后发到客户端
				result = new ServiceException("服务器返回头异常，请稍后再试:"+e);
				isException = true;
				e.printStackTrace();
			}
			try{
				// 解析返回结果，如果有异常则直接在解析层抛出
				return serializer.returnToBuffer(session, responseHeader,result, isException);
			}finally{
				
	//			logTime(method.getMethod().getName()+" returnToBuffer:");
			}
		}finally{
			Session.setCurrent(null);
		}
	}
}


